package cn.iocoder.yudao.module.pay.bank.service;

import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.common.exception.Assertions;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.util.BankUtils;
import cn.iocoder.yudao.module.pay.bank.bo.PayBankBO;
import cn.iocoder.yudao.module.pay.bank.convert.BankConvert;
import cn.iocoder.yudao.module.pay.bank.dal.dataobject.PayBankDO;
import cn.iocoder.yudao.module.pay.bank.dal.mysql.PayBankMapper;
import cn.iocoder.yudao.module.pay.bank.vo.PayBankCodeVO;
import cn.iocoder.yudao.module.pay.bank.vo.PayBankPageReqVO;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import java.util.*;

import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;

/**
 * 银行卡 Service 实现类
 *
 * @author 山野羡民
 */
@Service
@Validated
public class PayBankServiceImpl implements PayBankService {

    @Resource
    private PayBankMapper bankMapper;

    @Override
    public Long createBank(Long userId, PayBankBO bankBO) {
        ensureBankCardNoUnique(bankBO.getCardNo());
        // 插入
        PayBankDO bank = BankConvert.INSTANCE.convert(bankBO);
        bank.setUserId(userId);
        bank.setStatus(CommonStatusEnum.ENABLE.getStatus());
        bank.setIsDefault(false);
        bankMapper.insert(bank);
        // 返回
        return bank.getId();
    }

    @Override
    public void updateBank(Long userId, Long id, PayBankBO bankBO) {
        // 校验存在
        PayBankDO bankDO = ensureBankExists(id);
        Assertions.owner(userId, bankDO.getUserId());
        if (!Objects.equals(bankBO.getCardNo(), bankDO.getCardNo())) {
            ensureBankCardNoUnique(bankBO.getCardNo());
        }
        PayBankDO bank = BankConvert.INSTANCE.convert(bankBO);
        bank.setId(id);
        bank.setUserId(userId);
        bank.setStatus(CommonStatusEnum.ENABLE.getStatus());
        bank.setIsDefault(false);
        bankMapper.updateById(bank);
    }

    @Override
    public void deleteBank(Long userId, Long id) {
        // 校验存在
        PayBankDO bankDO = ensureBankExists(id);
        Assertions.owner(userId, bankDO.getUserId());
        // 删除
        bankMapper.deleteById(id);
    }

    private PayBankDO ensureBankExists(Long id) {
        PayBankDO bankDO = bankMapper.selectById(id);
        Assertions.notNull(bankDO, "银行卡信息不存在");
        return bankDO;
    }

    private void ensureBankCardNoUnique(String cardNo) {
        PayBankDO bankDO = bankMapper.selectOne(PayBankDO::getCardNo, cardNo);
        Assertions.isTrue(bankDO == null, "银行卡号已被占用");
    }

    @Override
    public PayBankDO getBank(Long id) {
        return bankMapper.selectById(id);
    }

    @Override
    public PayBankDO getDefaultBank(Long userId) {
        PayBankDO payBankDO = bankMapper.selectOne(PayBankDO::getUserId, userId, PayBankDO::getIsDefault, true);
        if (payBankDO == null) {
            List<PayBankDO> bankList = getBankList(userId, null);
            if (CollUtil.isEmpty(bankList)) {
                return null;
            }
            return bankList.get(0);
        }
        return payBankDO;
    }

    @Override
    public List<PayBankDO> getBankList(Long userId, Boolean isDefault) {
        List<PayBankDO> list = bankMapper.selectList(PayBankDO::getUserId, userId);
        if (CollUtil.isEmpty(list)) {
            return new ArrayList<>();
        }
        if (isDefault == null) {
            return list;
        }
        return list.stream().filter(bank -> Objects.equals(bank.getIsDefault(), isDefault)).toList();
    }

    @Override
    public PageResult<PayBankDO> getBankPage(PayBankPageReqVO pageReqVO) {
        return bankMapper.selectPage(pageReqVO);
    }

    @Override
    public List<PayBankCodeVO> getBankCodeList() {
        return BankUtils.getCodesByDefault().stream()
                .map(bankCode -> new PayBankCodeVO(bankCode.getCode(), bankCode.getName()))
                .toList();
    }

    @Override
    public Map<Long, PayBankDO> getBankMap(Collection<Long> ids) {
        List<PayBankDO> list = bankMapper.selectByIds(ids);
        if (CollUtil.isEmpty(list)) {
            return new HashMap<>();
        }
        return convertMap(list, PayBankDO::getId);
    }

    @Override
    public void updateDefaultBank(Long userId, Long id) {
        PayBankDO bankDO = bankMapper.selectById(id);
        Assertions.notNull(bankDO, "银行卡不存在");
        Assertions.owner(userId, bankDO.getUserId());
        List<PayBankDO> list = getBankList(userId, null);
        for (PayBankDO it : list) {
            it.setIsDefault(Objects.equals(it.getId(), id));
        }
        bankMapper.updateBatch(list);
    }

}
